/**
 * 智能分类服务
 * 基于关键词匹配的自动分类系统
 */

class ClassificationService {
  /**
   * 自动分类交易
   * @param {Object} transaction - 交易记录
   * @param {Array} categoryRules - 分类规则数组
   * @returns {Object|null} 分类结果
   */
  static async classifyTransaction(transaction, categoryRules) {
    try {
      const description = (transaction.description || '').toLowerCase();
      const merchant = (transaction.merchant || '').toLowerCase();
      const searchText = description + ' ' + merchant;

      if (!searchText.trim()) {
        return null;
      }

      const scores = [];

      // 遍历所有分类规则
      for (const rule of categoryRules) {
        const score = this.matchRule(searchText, rule);
        if (score > 0) {
          scores.push({
            category: rule.category,
            score: score * rule.weight,
            matched_keyword: rule.keyword,
            match_type: rule.match_type
          });
        }
      }

      // 如果没有匹配到任何规则
      if (scores.length === 0) {
        return {
          category: transaction.type === 'income' ? '其他收入' : '其他支出',
          confidence: 30,
          alternatives: [],
          is_default: true
        };
      }

      // 按得分排序
      scores.sort((a, b) => b.score - a.score);

      // 计算最佳匹配的置信度
      const totalScore = scores.reduce((sum, s) => sum + s.score, 0);
      const bestMatch = scores[0];
      const confidence = Math.min((bestMatch.score / totalScore) * 100, 100);

      return {
        category: bestMatch.category,
        confidence: confidence.toFixed(2),
        matched_keyword: bestMatch.matched_keyword,
        alternatives: scores.slice(1, 3).map(s => ({
          category: s.category,
          score: s.score.toFixed(2)
        })),
        is_default: false
      };

    } catch (error) {
      console.error('分类失败:', error.message);
      return null;
    }
  }

  /**
   * 关键词匹配
   * @param {string} text - 待匹配的文本
   * @param {Object} rule - 分类规则
   * @returns {number} 匹配分数
   */
  static matchRule(text, rule) {
    const keyword = rule.keyword.toLowerCase();
    const textLower = text.toLowerCase();

    switch (rule.match_type) {
      case 'exact':
        // 精确匹配
        return textLower === keyword ? 100 : 0;
      
      case 'startswith':
        // 开头匹配
        return textLower.startsWith(keyword) ? 80 : 0;
      
      case 'endswith':
        // 结尾匹配
        return textLower.endsWith(keyword) ? 70 : 0;
      
      case 'contains':
      default:
        // 包含匹配
        if (textLower.includes(keyword)) {
          // 关键词越长，匹配越准确
          const keywordLength = keyword.length;
          const baseScore = 60;
          const bonus = Math.min(keywordLength * 2, 30);
          return baseScore + bonus;
        }
        return 0;
    }
  }

  /**
   * 批量分类
   * @param {Array} transactions - 交易记录数组
   * @param {Array} categoryRules - 分类规则数组
   * @returns {Array} 分类结果数组
   */
  static async batchClassify(transactions, categoryRules) {
    const results = [];

    for (const transaction of transactions) {
      const classification = await this.classifyTransaction(transaction, categoryRules);
      results.push({
        transaction: transaction,
        classification: classification
      });
    }

    return results;
  }

  /**
   * 学习新规则（用户手动修正后）
   * @param {Object} transaction - 交易记录
   * @param {string} correctCategory - 正确的分类
   * @param {Object} db - 数据库连接
   * @returns {Array} 提取的关键词
   */
  static async learnFromCorrection(transaction, correctCategory, db) {
    try {
      // 从交易描述中提取关键词
      const keywords = this.extractKeywords(
        transaction.description || transaction.merchant || ''
      );
      
      if (keywords.length === 0) {
        return [];
      }

      // 为每个关键词创建或更新规则
      for (const keyword of keywords) {
        try {
          // 检查规则是否已存在
          const [existing] = await db.query(`
            SELECT id, hit_count, weight 
            FROM category_rules 
            WHERE category = ? AND keyword = ?
          `, [correctCategory, keyword]);

          if (existing.length > 0) {
            // 更新现有规则
            await db.query(`
              UPDATE category_rules 
              SET hit_count = hit_count + 1, 
                  weight = weight + 0.1,
                  updated_at = NOW()
              WHERE id = ?
            `, [existing[0].id]);
          } else {
            // 创建新规则
            await db.query(`
              INSERT INTO category_rules 
              (category, keyword, match_type, weight, hit_count) 
              VALUES (?, ?, 'contains', 1, 1)
            `, [correctCategory, keyword]);
          }
        } catch (error) {
          console.error(`创建规则失败 (${keyword}):`, error.message);
        }
      }

      return keywords;

    } catch (error) {
      console.error('学习规则失败:', error.message);
      return [];
    }
  }

  /**
   * 提取关键词
   * @param {string} text - 文本
   * @returns {Array} 关键词数组
   */
  static extractKeywords(text) {
    if (!text) return [];

    // 常用停用词
    const stopWords = [
      '的', '是', '在', '和', '等', '了', '中', '与', '为', '有',
      '我', '你', '他', '她', '它', '这', '那', '其',
      '支付', '购买', '消费', '付款'
    ];

    // 分词（简单实现，按空格、标点符号分割）
    const words = text
      .split(/[\s\-_\/\(\)\[\]\{\}（）【】《》。，、！？；：""'']+/)
      .map(w => w.trim())
      .filter(w => w.length >= 2) // 至少2个字符
      .filter(w => !stopWords.includes(w)); // 过滤停用词

    // 去重并限制数量
    const uniqueWords = [...new Set(words)];
    return uniqueWords.slice(0, 3); // 最多返回3个关键词
  }

  /**
   * 获取分类统计
   * @param {Array} classifications - 分类结果数组
   * @returns {Object} 统计信息
   */
  static getClassificationStats(classifications) {
    const stats = {
      total: classifications.length,
      auto_classified: 0,
      default_classified: 0,
      high_confidence: 0,
      low_confidence: 0,
      by_category: {}
    };

    for (const result of classifications) {
      const classification = result.classification;
      
      if (!classification) continue;

      if (classification.is_default) {
        stats.default_classified++;
      } else {
        stats.auto_classified++;
        
        if (classification.confidence >= 80) {
          stats.high_confidence++;
        } else if (classification.confidence < 50) {
          stats.low_confidence++;
        }
      }

      // 按分类统计
      const category = classification.category;
      if (!stats.by_category[category]) {
        stats.by_category[category] = 0;
      }
      stats.by_category[category]++;
    }

    return stats;
  }
}

module.exports = ClassificationService;

